/*************************************************************
* 
*  DS_EVENT_PIPES.CPP
*
*************************************************************/
#include <ap/settings/ds_settings.h>
#include "ds_event_pipes.h"

#include <ssl/ssl.h>

extern sslSYSTEM *gsSslSystem;

/*************************************************************
* dsPIPE::AddEvent()
* 
*************************************************************/
void dsPIPE::AddEvent (dsSTRID name, const dsVECTOR_PARAM_LIST& params)
{
   if (reader->IsValid()) {
      if (! reader->HandleEvent(name, params, true)) {
         apLog("~Pipe,Error~pipe <%s>: failed to handle event %s", pipeName.CStr(), name.CStr());
      }
   } else {
      eventQueue.PushBack(EVENT_REC(name, params));
   }
}

/*************************************************************
* dsPIPE::RegisterReader()
* 
*************************************************************/
bool dsPIPE::RegisterReader (refPIPE_READER r)
{
   if (reader->IsValid()) {
      apLog("~Pipe,Error~pipe <%s>: RegisterReader failed: reader already exists", pipeName.CStr());
      return false;
   }

   reader = r;

   // Dispatch events
   for (EVENT_QUEUE_STORAGE::ITERATOR iter = eventQueue.Begin(); !iter.IsDone(); ++iter) {
	   EVENT_QUEUE_STORAGE::ITERATOR nextIter = iter;
	   ++nextIter;
	   reader->HandleEvent(iter->name, iter->params, nextIter.IsDone());
   }
   eventQueue.Clear();
   return true;
}

/*************************************************************
* dsPIPE::UnregisterReader()
* 
*************************************************************/
bool dsPIPE::UnregisterReader ()
{
   if (! reader->IsValid()) {
      apLog("~Pipe,Error~pipe <%s>: UnregisterReader failed: reader doesnt exist", pipeName.CStr());
      return false;
   }

   reader = refPIPE_READER();
   return true;
}

bool dsPIPE::IsEmpty() const
{
	return eventQueue.IsEmpty();	
}

/*************************************************************
* dsPIPE_MGR::CreatePipe()
* 
*************************************************************/
bool dsPIPE_MGR::CreatePipe (dsSTRID name)
{
   dsPIPE pipe(name);
   if (namedPipes.InsertSorted(pipe, dsPIPE::CMP(), dsVECTOR<dsPIPE>::INS_DUP_ERROR) == -1) {
      apLog("~Pipe,Error~pipe <%s>: failed create pipe: pipe already exists", name.CStr());
      return false;
   }

   return true;
}

/*************************************************************
* dsPIPE_MGR::FireEvent()
* 
*************************************************************/
int dsPIPE_MGR::GetPipeIdx (const dsSTRID& pipe) const
{
   int idx = namedPipes.FindSorted(pipe, dsPIPE::CMP());
   if (idx == -1) {
      apLog("~Pipe,Error~pipe <%s>: failed to find, pipe doesnt exist", pipe.CStr());
   }
   return idx;
}

/*************************************************************
* dsPIPE_MGR::FireEvent()
* 
*************************************************************/
void dsPIPE_MGR::FireEvent (dsSTRID pipe, dsSTRID name, refParamList params)
{
   int idx = GetPipeIdx(pipe);
   if (idx != -1) {
      namedPipes[idx].AddEvent(name, *params.Get());
   }
}

/*************************************************************
* dsPIPE_MGR::FireEvent()
* 
*************************************************************/
void dsPIPE_MGR::FireEvent (dsSTRID pipe, dsSTRID name, dsVECTOR_PARAM_LIST& params)
{
   int idx = GetPipeIdx(pipe);
   if (idx != -1) {
      namedPipes[idx].AddEvent(name, params);
   }
}

/*************************************************************
* dsPIPE_MGR::RegisterReader()
* 
*************************************************************/
bool dsPIPE_MGR::RegisterReader (dsSTRID pipe, refPIPE_READER r)
{
   int idx = namedPipes.FindSorted(pipe, dsPIPE::CMP());
   if (idx == -1) {
      apLog("~Pipe,Error~pipe <%s>: failed to register reader: pipe doesnt exist", pipe.CStr());
      return false;
   }

   return namedPipes[idx].RegisterReader(r);
}

/*************************************************************
* dsPIPE_MGR::RegisterReader()
* 
*************************************************************/
bool dsPIPE_MGR::RegisterReader (dsSTRID pipe, sslOBJ_REF obj, dsSTRID name)
{
   int idx = namedPipes.FindSorted(pipe, dsPIPE::CMP());
   if (idx == -1) {
      apLog("~Pipe,Error~pipe <%s>: failed to register reader: pipe doesnt exist", pipe.CStr());
      return false;
   }

   refPIPE_READER r(apNEW dsPIPE_READER_SSL(obj, name), ds_data::opRefCount);

   return namedPipes[idx].RegisterReader(r);
}

/*************************************************************
* dsPIPE_MGR::UnregisterReader()
* 
*************************************************************/
bool dsPIPE_MGR::UnregisterReader (dsSTRID pipe)
{
   int idx = namedPipes.FindSorted(pipe, dsPIPE::CMP());
   if (idx == -1) {
      apLog("~Pipe,Error~pipe <%s>: failed to unregister reader: pipe doesnt exist", pipe.CStr());
      return false;
   }

   return namedPipes[idx].UnregisterReader();
}

bool dsPIPE_MGR::IsPipeEmpty(dsSTRID pipe) const
{
	int idx = namedPipes.FindSorted(pipe, dsPIPE::CMP());
	if (idx == -1) {
		apLog("~Pipe,Error~pipe <%s>: failed to unregister reader: pipe doesnt exist", pipe.CStr());
		return false;
	}

	return namedPipes[idx].IsEmpty();
}

/*************************************************************
* dsPIPE_MGR::dsPIPE_MGR()
* 
*************************************************************/
dsPIPE_MGR::dsPIPE_MGR ()
{  
   SSL_INIT_OBJ_USING_EXPORT_MAP(dsPIPE_MGR, sslObject, sslPipesMgr)
}

/*************************************************************
* dsPIPE_MGR::~dsPIPE_MGR()
* 
*************************************************************/
dsPIPE_MGR::~dsPIPE_MGR ()
{
   SSL_TERM_OBJ(sslObject)
}

dsPIPE_MGR  *gPipesMgr;

/*************************************************************
* dsInitPipeMgr()
* 
*************************************************************/
BOOL dsInitPipeMgr (void)
{
   if (gPipesMgr) {
      apLog("~Pipe,Error~ Pipe manager already initialized");
      return TRUE;
   }

   gPipesMgr = apNEW dsPIPE_MGR;

   return TRUE;
}

/*************************************************************
* dsTermPipeMgr()
* 
*************************************************************/
void dsTermPipeMgr (void)
{
   if (gPipesMgr) {
      apLog("~Pipe,Error~ Pipe manager has not been initialized");
      return;
   }

   delete gPipesMgr;
   gPipesMgr = NULL;
}

//
// End of file DS_EVENT_PIPES.CPP
//